package yl.hs.bmipfull.service.flow.impl;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import yl.hs.bmipfull.daos.flow.IFlowInfoDao;
import yl.hs.bmipfull.daos.flow.IFlowNodeDao;
import yl.hs.bmipfull.daos.system.IGlobalSearchItemDao;
import yl.hs.bmipfull.pojo.flow.FlowConditionEntity;
import yl.hs.bmipfull.pojo.flow.FlowInfoEntity;
import yl.hs.bmipfull.pojo.flow.FlowNodeEntity;
import yl.hs.bmipfull.pojo.flow.FlowNodeHandlersEntity;
import yl.hs.bmipfull.pojo.system.GlobalSearchItemEntity;
import yl.hs.bmipfull.pojo.system.UserInfoEntity;
import yl.hs.bmipfull.service.flow.IFlowConditionService;
import yl.hs.bmipfull.service.flow.IFlowInfoService;
import yl.hs.bmipfull.service.flow.IFlowNodeHandlersService;
import yl.hs.bmipfull.service.flow.IFlowNodeService;
import yl.hs.bmipfull.service.system.IUserService;
import yl.hs.bmipfull.service.system.impl.SystemBaseService;
import yl.hs.bmipfull.utils.DataState;
import yl.hs.bmipfull.utils.Tl;
import yl.hs.bmipfull.utils.datastate.ActionType;
import yl.hs.bmipfull.utils.datastate.FlowInfoState;
import yl.hs.bmipfull.viewmodels.PageQuery;
import yl.hs.bmipfull.viewmodels.PageResult;
import yl.hs.bmipfull.viewmodels.flow.FlowInfoViewModel;

import java.util.List;
import java.util.Map;

/**
 * 作用:  流程信息服务层接口实现<br/>
 * 创建时间: 2021年06月22日 14时30分49秒 <br/>
 *
 * @author 张凯
 */
@Service
public class FlowInfoServiceImpl extends SystemBaseService implements IFlowInfoService {

    @Autowired
    IFlowInfoDao dao;

    @Autowired
    IFlowNodeService nodeService;

    @Autowired
    IFlowNodeDao nodeDao;

    @Autowired
    IFlowNodeHandlersService handlersService;

    @Autowired
    IFlowConditionService conditionService;

    @Autowired
    IUserService userService;

    @Autowired
    IGlobalSearchItemDao searchItemDao;

    @Override
    public List<FlowInfoEntity> queryList(PageQuery pageQuery) throws Exception {
        pageQuery.checkSortSides(FlowInfoEntity.class);
        return dao.queryPage(pageQuery.getQuery());
    }

    @Override
    public PageResult<FlowInfoEntity> queryPage(PageQuery pageQuery, int rowNum, int page) throws Exception {
        pageQuery.checkSortSides(FlowInfoEntity.class);
        pageQuery.getQuery().put("querySkip", (page - 1) * rowNum);
        pageQuery.getQuery().put("pageSize", rowNum);

        PageResult<FlowInfoEntity> result = new PageResult(rowNum);
        result.setRecords(dao.queryCountByCondition(pageQuery.getQuery()));
        result.setPage(page);
        result.setData(dao.queryPage(pageQuery.getQuery()));
        return result;
    }


    @Override
    public FlowInfoEntity findBySn(String sn) {
        return dao.findBySN(sn);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveFlowInfo(FlowInfoViewModel flowInfoViewModel) throws Exception {
        Integer result = 0;
        Integer saveFlowInfoResult = saveFlowInfo(flowInfoViewModel.getFlowInfo());
        String flowSn = flowInfoViewModel.getFlowInfo().getSn();
        if (saveFlowInfoResult > 0) {
            result += saveFlowInfoResult;
            writeLog(ActionType.UPDATE, flowSn, "保存流程信息", Tl.toJson(flowSn), FlowInfoEntity.class);
            //保存节点信息
            for (FlowNodeEntity flowNode : flowInfoViewModel.getNodeList()) {
                String oldSn = flowNode.getSn();
                flowNode.setFlowSN(flowSn);
                flowNode.setState(DataState.CREATED.code);
                Integer saveNodeResult = nodeService.saveFlowNode(flowNode);
                result += saveFlowInfoResult;
                if (saveNodeResult > 0) {
                    if (flowNode.getHandlers() != null && flowNode.getHandlers().length > 0) {
                        for (String handlerSn : flowNode.getHandlers()) {
                            UserInfoEntity userInfo = userService.findUserBySN(handlerSn);
                            if (userInfo != null) {
                                FlowNodeHandlersEntity nodeHandler = new FlowNodeHandlersEntity(userInfo.getSn(),
                                        userInfo.getRealname(), flowNode.getSn(), flowSn);
                                handlersService.saveFlowNodeHandlers(nodeHandler);
                            }
                        }
                    }
                }
                for (FlowConditionEntity condition : flowInfoViewModel.getConditions()) {

                    if (oldSn.equals(condition.getLeftNodeSn())) {
                        condition.setLeftNodeSn(flowNode.getSn());
                    }
                    if (oldSn.equals(condition.getRightNodeSn())) {
                        condition.setRightNodeSn(flowNode.getSn());
                    }
                }
            }
            for (FlowConditionEntity condition : flowInfoViewModel.getConditions()) {
                condition.setFlowSn(flowSn);
                conditionService.saveFlowCondition(condition);
            }
        }
        return result;
    }

    @Override
    public Integer saveFlowInfo(FlowInfoEntity flowInfo) throws Exception {
        if (!Tl.isEmpty(flowInfo.getSn())) {
            dao.changeStateByDataTypeCode(flowInfo.getDataTypeCode(), FlowInfoState.Abandoned.code);
        }
        GlobalSearchItemEntity searchItemEntity = searchItemDao.findItemByDataCode(flowInfo.getDataTypeCode());
        if (searchItemEntity != null) {
            flowInfo.setDataTypeName(searchItemEntity.getDataType());
        }
        flowInfo.setSn(queryNewSN(FlowInfoEntity.class));
        flowInfo.setPYFieldValue();
        return dao.insertNew(flowInfo);
    }


    @Override
    @Transactional
    public Integer delete(String sn) {
        return delete(sn.split(","));
    }

    @Override
    public FlowInfoEntity findByDataTypeAndState(String dataTypeCode, short state) {
        //if(dataTypeCode.equals())

        return dao.findByDataTypeAndState(dataTypeCode, state);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer saveFlowInfo(Map<String, Object> model, String sn) throws Exception {
        Integer result = 0;
        FlowInfoEntity entity = null;
        if (Tl.isEmpty(sn)) {
            //执行保存
            entity = new FlowInfoEntity();
            Tl.getChangeLog(entity, model);
            GlobalSearchItemEntity searchItemEntity = searchItemDao.findItemByDataCode(entity.getDataTypeCode());
            if (searchItemEntity != null) {
                entity.setDataTypeName(searchItemEntity.getDataType());
            }
            entity.setPYFieldValue();
            entity.setSn(queryNewSN(FlowInfoEntity.class));
            result = dao.insertNew(entity);
            if (result > 0) {
                writeLog(ActionType.CREATE, entity.getSn(), "插入流程信息信息", Tl.toJson(entity), FlowInfoEntity.class);
            }

        } else {
            //执行修改
            entity = findBySn(sn);
            Tl.getChangeLog(entity, model);
            GlobalSearchItemEntity searchItemEntity = searchItemDao.findItemByDataCode(entity.getDataTypeCode());
            if (searchItemEntity != null) {
                entity.setDataTypeName(searchItemEntity.getDataType());
            }
            entity.setPYFieldValue();
            result = dao.update(entity);
            if (result > 0) {
                writeLog(ActionType.UPDATE, sn, "更新流程信息信息", Tl.toJson(entity), FlowInfoEntity.class);
            }
        }
        return result;
    }

    @Override
    public Boolean checkDataTypeCode(String dataTypeCode, String sn) {
        List<FlowInfoEntity> flowInfoList = dao.queryByDataTypeAndNotState(dataTypeCode, FlowInfoState.Abandoned.code);
        if (flowInfoList != null && flowInfoList.size() > 0) {
            if (Tl.isEmpty(sn)) {
                return true;
            } else {
                List<FlowInfoEntity> flowInfo = flowInfoList.stream().filter(t -> sn.equals(t.getSn())).toList();
                if (flowInfo != null && flowInfo.size() > 0) {
                    return false;
                } else {
                    return true;
                }
            }
        } else {
            return false;
        }
    }

    @Override
    public Integer updateStateByState(short setState, short whereState) {
        return dao.updateStateByState(setState, whereState);
    }

    @Override
    @Transactional
    public Integer delete(String[] sn) {
        Integer result = dao.changeStateBySN(sn, DataState.DELETED.code);
        if (result > 0) {
            writeLog(ActionType.DELETE, sn, FlowInfoEntity.class);
        }
        return result;
    }
}